//
//@author jltxseo
// Created by junlintianxia on 2016/4/14.
//
//#include<stdio.h>
#include <string.h>
#include <jni.h>
#include<malloc.h>
#include <android/log.h>
#include "cn_jltx_javajni_IDataProvider.h"

#define LOG_TAG "ndk.out.c"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)


/**
 * 返回值 char* 这个代表char数组的首地址
 *  Jstring2CStr 把java中的jstring的类型转化成一个c语言中的char 字符串
 */
char *Jstring2CStr(JNIEnv *env, jstring jstr) {
    char *rtn = NULL;
    jclass clsstring = env->FindClass("java/lang/String"); //String
    jstring strencode = env->NewStringUTF("utf-8");  // 得到一个java字符串 "utf-8"
    jmethodID mid = env->GetMethodID(clsstring, "getBytes",
                                     "(Ljava/lang/String;)[B"); //[ String.getBytes("utf-8");
    jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid,
                                                         strencode); // String .getByte("utf-8");
    jsize alen = env->GetArrayLength(barr); // byte数组的长度
    jbyte *ba = env->GetByteArrayElements(barr, JNI_FALSE);
    if (alen > 0) {
        rtn = (char *) malloc(alen + 1);         //"\0"
        memcpy(rtn, ba, alen);
        rtn[alen] = 0;
    }
    env->ReleaseByteArrayElements(barr, ba, 0);  //
    return rtn;
}

/**
 * char* to jstring
 */
/*jstring stoJstring(JNIEnv* env, const char* pat)
{
    jclass strClass = env->FindClass("Ljava/lang/String;");
    jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
    jbyteArray bytes = env->NewByteArray(strlen(pat));
    env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat);
    jstring encoding = env->NewStringUTF("utf-8");
    return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
}*/


JNIEXPORT jint JNICALL
Java_cn_jltx_javajni_IDataProvider_add(JNIEnv *env, jobject obj, jint x, jint y) {
    LOGD("x = %d", x);
    LOGD("y = %d", y);
    return x + y;
}

JNIEXPORT jstring JNICALL Java_cn_jltx_javajni_IDataProvider_sayHelloInC
        (JNIEnv *env, jobject obj, jstring jstr) {
    //在c语言中 是没有java的String   jsring转换成c中的char
    char *cstr = Jstring2CStr(env, jstr);
    LOGD("cstr=%s", cstr);
    // c语言中的字符串 都是以'/0' 作为结尾
    char arr[7] = {' ', 'h', 'e', 'l', 'l', 'o', '\0'};
    strcat(cstr, arr);
    LOGD("new cstr=%s", cstr);
    return env->NewStringUTF(cstr);  //用给定的char*字符串创建java字符串
}

JNIEXPORT jintArray JNICALL Java_cn_jltx_javajni_IDataProvider_intMethod
        (JNIEnv *env, jobject obj, jintArray jary) {
    //1.知道数组的长度
    //2.操作这个数组里面的每一个元素
    int len = env->GetArrayLength(jary);
    LOGD("shuzu len=%d", len);
    jint *intarr = env->GetIntArrayElements(jary, 0);
    int i = 0;
    for (; i < len; i++) {
        LOGD("intarr[%d] = %d", i, intarr[i]);
        *(intarr + i) += 10;
//        intarr[i] +=10;
    }
    env->ReleaseIntArrayElements(jary, intarr, 0); // c语言释放掉 刚才申请的内存空间
    LOGD("ReleaseIntArrayElements");
    return jary;
}

/*
 * 通过构造一个数组的数组， 返回 一个二维数组的形式
 * Class:     cn_jltx_javajni_IDataProvider
 * Method:    getTwoArray
 * Signature: (I)[[I
 */
JNIEXPORT jobjectArray JNICALL Java_cn_jltx_javajni_IDataProvider_getTwoArray
        (JNIEnv *env, jobject obj, jint dimion) {
    jclass intArrayClass = env->FindClass("[I"); //获得一维数组 的类引用，即jintArray类型
    //构造一个指向jintArray类一维数组的对象数组，该对象数组初始大小为dimion
    jobjectArray obejctIntArray = env->NewObjectArray(dimion, intArrayClass, NULL);

    //构建dimion个一维数组，并且将其引用赋值给obejctIntArray对象数组
    for (int i = 0; i < dimion; i++) {
        //构建jint型一维数组
        jintArray intArray = env->NewIntArray(dimion);

        jint temp[10];  //初始化一个容器，假设 dimion  < 10 ;
        for (int j = 0; j < dimion; j++) {
            temp[j] = i + j; //赋值
        }

        //设置jit型一维数组的值
        env->SetIntArrayRegion(intArray, 0, dimion, temp);
        //给object对象数组赋值，即保持对jint一维数组的引用
        env->SetObjectArrayElement(obejctIntArray, i, intArray);

        env->DeleteLocalRef(intArray);  //删除局部引用
    }

    return obejctIntArray; //返回该对象数组
}
